package crontab

import (
	"booking/models"
	"time"

	"gorm.io/gorm"
)

// GenerateOrderStats 汇总订单统计数据（按“第二天跑前一天”的方式触发 daily/weekly/monthly/yearly）
func GenerateOrderStats() {
	var db = models.Db
	now := time.Now()
	// 要统计的日期为昨天（第二天跑前一天）
	processDate := now.AddDate(0, 0, -1)

	// 每日统计（统计 processDate）
	if err := aggregateOrderStats(db, "daily", processDate); err != nil {
	}

	// 每周统计：在周一执行，统计上周（周一~周日），processDate 在周一时为昨天（周日）
	if now.Weekday() == time.Monday {
		if err := aggregateOrderStats(db, "weekly", processDate); err != nil {
		}
	}

	// 每月统计：在每月 1 日执行，统计上月（1号跑，processDate 是上月最后一天）
	if now.Day() == 1 {
		if err := aggregateOrderStats(db, "monthly", processDate); err != nil {
		}
	}

	// 每年统计：在每年 1 月 1 日执行，统计上一年（1月1日跑，processDate 是上一年 12 月 31 日）
	if now.Month() == time.January && now.Day() == 1 {
		if err := aggregateOrderStats(db, "yearly", processDate); err != nil {
		}
	}

	return
}

// aggregateOrderStats 以传入的 "now" 作为周期的最后一天（statDate），计算该周期 [startDate, endDate) 的数据
func aggregateOrderStats(db *gorm.DB, statType string, now time.Time) error {
	var startDate, endDate time.Time
	loc := now.Location()

	switch statType {
	case "daily":
		// now 是要统计的那一天（例如昨天），统计该日 00:00:00 到次日 00:00:00（左闭右开）
		startDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
		endDate = startDate.AddDate(0, 0, 1)
	case "weekly":
		// now 是周的最后一天（期望为周日），统计上周的周一 00:00 到下周一 00:00（即 next day of now）
		// 计算周一（上一周的第一天）
		// 确保以周一作为一周开始：start = now -6 days
		startDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -6)
		endDate = startDate.AddDate(0, 0, 7)
	case "monthly":
		// now 是要统计的那个月的最后一天（例如：当 now 是 2025-09-30）
		startDate = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc)
		// endDate 为下月第一天
		endDate = startDate.AddDate(0, 1, 0)
	case "yearly":
		// now 是要统计的那一年的最后一天（例如：2024-12-31）
		startDate = time.Date(now.Year(), time.January, 1, 0, 0, 0, 0, loc)
		endDate = time.Date(now.Year()+1, time.January, 1, 0, 0, 0, 0, loc)
	default:
		return nil
	}

	// 统计 period 的状态分组数量和金额
	var results []struct {
		Status int
		Count  int
		Amount float64
	}

	// 按 created_time 统计（如果你想按完成时间统计，可把 where 中的字段改成 complete_date）
	if err := db.Model(&models.Order{}).
		Select("status, COUNT(*) AS count, SUM(total_amount) AS amount").
		Where("created_time >= ? AND created_time < ?", startDate, endDate).
		Group("status").
		Scan(&results).Error; err != nil {
		return err
	}

	// 填充 stats
	stats := models.OrderStats{
		StatType: statType,
		StatDate: time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc),
	}

	for _, r := range results {
		switch r.Status {
		case 1:
			stats.Status1Count = r.Count
			stats.Status1Amount = r.Amount
		case 2:
			stats.Status2Count = r.Count
			stats.Status2Amount = r.Amount
		case 3:
			stats.Status3Count = r.Count
			stats.Status3Amount = r.Amount
		case 4:
			stats.Status4Count = r.Count
			stats.Status4Amount = r.Amount
		}
		stats.TotalCount += r.Count
		stats.TotalAmount += r.Amount
	}

	// 插入或更新统计表
	var existing models.OrderStats
	err := db.Where("stat_type = ? AND stat_date = ?", statType, stats.StatDate).First(&existing).Error
	if err == gorm.ErrRecordNotFound {
		return db.Create(&stats).Error
	} else if err != nil {
		return err
	}

	// 更新已有记录（保持 ID）
	stats.Id = existing.Id
	return db.Model(&existing).Updates(&stats).Error
}
